package com.common.core;

import java.io.IOException;
import java.lang.reflect.Type;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.gitee.magic.context.ConverterEditorUtils;
import com.gitee.magic.core.exception.ApplicationException;
import com.gitee.magic.framework.base.context.HttpHolder;
import com.gitee.magic.framework.base.rest.BusinessRestException;
import com.gitee.magic.framework.base.rest.HttpWrapper;
import com.gitee.magic.framework.head.converter.SerializeConverterEditor;
import com.gitee.magic.framework.head.vo.BaseVO;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.Util;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import jakarta.servlet.http.HttpServletRequest;

/**
 * @author start
 */
public class ServiceFeignSerializeConfiguration implements RequestInterceptor, Encoder, Decoder,ErrorDecoder {

	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Override
	public void apply(RequestTemplate requestTemplate) {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if(attributes!=null) {
			HttpServletRequest request = attributes.getRequest();
			requestTemplate.header(HttpHolder.REQUESTID, HttpHolder.getRequestId(request));
			requestTemplate.header(HttpWrapper.AUTHORIZATION, request.getHeader(HttpWrapper.AUTHORIZATION));
		}
		requestTemplate.header(HttpWrapper.CONTENTTYPE, HttpWrapper.CONTENTTYPE_JSON);
		requestTemplate.header(HttpWrapper.ACCEPT, HttpWrapper.CONTENTTYPE_SERIALIZE);
	}

	@Override
	public void encode(Object object, Type bodyType, RequestTemplate template) {
		String content=ConverterEditorUtils.converterObject(object).toString();
		template.body(content);
	}

	@Override
	public Object decode(Response response, Type type) {
		String responseContent=responseContent(response);
		if(responseContent==null) {
			return null;
		}
		SerializeConverterEditor editor=new SerializeConverterEditor(Object.class);
		editor.setValue(responseContent);
		Object vo=null;
		try {
			vo=editor.converter();
		}catch(Exception e) {
			if(logger.isErrorEnabled()) {
				logger.error("response status:{} content:{}",response.status(),responseContent);
			}
			throw new ApplicationException(e);
		}
		if(BaseVO.class.equals(vo.getClass())) {
			BaseVO v=(BaseVO)vo;
			if(v.getCode()!=HttpStatus.OK.value()) {
				throw new BusinessRestException(v.getMessage(),v.getCode(),v.getMessage(),v.getLogno(),v.getName());
			}
		}
		return vo;
	}

	@Override
	public Exception decode(String methodKey, Response response) {
		Object result=decode(response,null);
		if(result==null) {
			return null;
		}
		BaseVO v=(BaseVO)result;
		return new BusinessRestException(v.getMessage(), v.getCode(), v.getMessage(), v.getLogno(), v.getName());
	}

	public String responseContent(Response response) {
		if (response.body() == null) {
			return null;
		}
		try {
			return Util.toString(response.body().asReader(Util.UTF_8));
		} catch (IOException e) {
			throw new ApplicationException(e);
		}
	}
	
}
